package api

import (
	"context"
	"errors"
	"fmt"
	"net/http"
	"time"

	"github.com/dchest/captcha"
	"github.com/gin-gonic/gin"
	global "github.com/smash-llj/Nexa-server/global"
	"github.com/spf13/viper"
)

type CaptchaApi struct {
	BaseApi
}

func NewCaptchaApi() CaptchaApi {
	return CaptchaApi{
		BaseApi: NewBaseApi(),
	}
}

var timeout = time.Duration(viper.GetInt("Captcha.timeout")) * time.Minute

// GenerateCaptcha 生成验证码
func (c *CaptchaApi) GenerateCaptcha(ctx *gin.Context) {
	captchaId := captcha.New()
	digits := captcha.RandomDigits(6)
	captchaStr := ""
	for _, digit := range digits {
		captchaStr += fmt.Sprintf("%d", digit)
	}
	err := global.Redis.Set(context.Background(), captchaId, captchaStr, timeout).Err()
	if err != nil {
		c.Fail(Response{
			Msg: "验证码出现错误",
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"captchaId":   captchaId,
		"captcha_url": fmt.Sprintf("/captcha?id=%s", captchaId),
	})
}

// ServeCaptchaImage 返回验证码图片
func (c *CaptchaApi) ServeCaptchaImage(ctx *gin.Context) {
	captchaId := ctx.Query("id")
	if captchaId == "" {
		ctx.JSON(400, gin.H{
			"msg": "验证码id不能为空",
		})
		return
	}

	digits, err := global.Redis.Get(context.Background(), captchaId).Result()
	if err != nil {
		ctx.JSON(400, gin.H{
			"msg": "验证码错误或过期",
		})
		return
	}
	digitBytes := make([]byte, len(digits))
	for i := range digits {
		digitBytes[i] = digits[i] - '0' // 将字符转为数字，例如 '1' -> 1
	}

	img := captcha.NewImage(captchaId, digitBytes, 240, 80)
	ctx.Header("Content-Type", "image/png")
	_, err = img.WriteTo(ctx.Writer)
	if err != nil {
		ctx.JSON(500, gin.H{
			"msg": "生成验证码图片失败",
		})
		return
	}
}

// VerifyCaptcha 校验验证码
func VerifyCaptcha(captchaId, captchaVal string) (bool, error) {
	fmt.Println(captchaId, captchaVal)
	storedCaptcha, err := global.Redis.Get(context.Background(), captchaId).Result()
	if err != nil {
		return false, errors.New("验证码过期")
	}
	if storedCaptcha != captchaVal {
		return false, errors.New("验证码错误")
	}
	_, err = global.Redis.Del(context.Background(), captchaId).Result()
	return true, nil
}
